package com.secsbrain.deploy.web.controller;

import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.secsbrain.cmdb.client.iface.AppInfoService;
import com.secsbrain.cmdb.client.model.Server;
import com.secsbrain.deploy.biz.utils.DeployUtils;
import com.secsbrain.deploy.biz.IBuildModelService;
import com.secsbrain.deploy.biz.IBuildTemplateService;
import com.secsbrain.deploy.client.iface.ModelService;
import com.secsbrain.deploy.client.model.BuildModelDto;
import com.secsbrain.deploy.client.model.DeployParam;
import com.secsbrain.deploy.dal.model.BuildModel;
import com.secsbrain.deploy.dal.model.BuildTemplate;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.secsbrain.cmdb.client.model.AppDetail;
import com.secsbrain.common.ErrorCodeEnum;
import com.secsbrain.common.ResponseVo;

/**
 * 构建相关控制层
 *
 * @author zhaoyi
 */
@RestController
public class ModelServiceImpl implements ModelService {

    private static final Logger logger = LoggerFactory.getLogger(ModelServiceImpl.class);

    @Autowired
    IBuildModelService buildModelService;

    @Autowired
    AppInfoService appInfoService;

    @Autowired
    IBuildTemplateService buildTemplateService;

    /* (non-Javadoc)
     * @see DeployService#createDeployJob(DeployParam)
     */
    @Override
    public ResponseVo<?> createDeployJob(@RequestBody DeployParam deployParam) {
        Assert.notNull(deployParam.getAppId(), "appId不能为空");
        Assert.hasText(deployParam.getEnvName(), "环境名称不能为空");

        BuildModel buildModelParam = new BuildModel();
        buildModelParam.setAppId(deployParam.getAppId());
        buildModelParam.setEnv(deployParam.getEnvName());
        int count = buildModelService.selectCount(buildModelParam);
        Assert.isTrue(count <= 0, "该应用已存在构建模型");

        //1.查出应用
        ResponseVo<AppDetail> responseVo = appInfoService.queryAppDetailById(deployParam.getAppId());
        if(!responseVo.isSuccess()){
            logger.error("queryAppDetailById error,params:{},result:{}",deployParam.getAppId(), JSON.toJSONString(responseVo));
        }
        Assert.isTrue(responseVo.isSuccess(), responseVo.getMsg());
        //2.根据应用类型，查询jenkins模板配置
        AppDetail appDetail = responseVo.getData();
        this.valicateDeployParams(appDetail, deployParam);

        BuildTemplate buildTemplateParam = new BuildTemplate();
        buildTemplateParam.setSystemType(appDetail.getSystemType());
        BuildTemplate buildTemplate = buildTemplateService.selectOne(buildTemplateParam);
        Assert.notNull(buildTemplate, "没有找到构建模板，请联系管理员");
        //3.创建jenkins 配置
        try {
            buildModelService.createBuildModel(buildTemplate.getName(), deployParam, appDetail);
        } catch (RuntimeException e) {
            logger.error("创建deploy job失败", e);
            return ErrorCodeEnum.ERROR_COMMON_SYSTEM.getResponseVo("创建构建任务失败：" + e.getMessage());
        } catch (Exception e) {
            logger.error("创建deploy job异常", e);
            return ErrorCodeEnum.ERROR_COMMON_SYSTEM.getResponseVo("创建构建任务失败！请联系管理员处理");
        }

        return ResponseVo.getSuccessResponse();
    }

    /* (non-Javadoc)
     * @see DeployService#updateDeployJob(DeployParam)
     */
    @Override
    public ResponseVo<?> updateDeployJob(@RequestBody DeployParam deployParam) {
        Assert.notNull(deployParam.getAppId(), "appId不能为空");
        Assert.hasText(deployParam.getEnvName(), "环境名称不能为空");

        BuildModel buildModelParam = new BuildModel();
        buildModelParam.setAppId(deployParam.getAppId());
        buildModelParam.setEnv(deployParam.getEnvName());
        BuildModel buildModel = buildModelService.selectOne(buildModelParam);
        Assert.isTrue(buildModel != null, "该应用不存在构建任务");

        //1.查出应用
        ResponseVo<AppDetail> responseVo = appInfoService.queryAppDetailById(deployParam.getAppId());
        Assert.isTrue(responseVo.isSuccess(), responseVo.getMsg());
        //2.根据应用类型，查询jenkins模板配置
        AppDetail appDetail = responseVo.getData();
        this.valicateDeployParams(appDetail, deployParam);

        try {
            buildModelService.updateBuildModel(deployParam, appDetail);
        } catch (RuntimeException e) {
            logger.error("更新构建任务失败", e);
            return ErrorCodeEnum.ERROR_COMMON_SYSTEM.getResponseVo("更新构建任务失败：" + e.getMessage());
        } catch (Exception e) {
            logger.error("更新deploy job异常", e);
            return ErrorCodeEnum.ERROR_COMMON_SYSTEM.getResponseVo("更新构建任务失败！请联系管理员处理");
        }

        return ResponseVo.getSuccessResponse();

    }

    /**
     * 功能描述: <br>
     * 校验创建构建参数
     *
     * @param appDetail
     * @param deployParam
     */
    private void valicateDeployParams(AppDetail appDetail, DeployParam deployParam) {
        if (deployParam.isSwitchflow()) {
            Assert.hasText(deployParam.getSwitchEnvName(), "切流环境名称不能为空");
        }
        Assert.hasText(appDetail.getSystemType(), "systemType不能为空，请联系管理员");
        if (DeployUtils.isLinuxNec(appDetail.getSystemType())) {
            Assert.hasText(deployParam.getTargetPath(), "targetPath不能为空");
            if (!deployParam.isK8sFlag()) {
                Assert.hasText(deployParam.getRemoteFloder(), "remoteFloder不能为空");
                Assert.hasText(deployParam.getRemoteCmdPath(), "remoteCmdPath不能为空");
            }
        } else if (DeployUtils.isStaticNec(appDetail.getSystemType())) {
            Assert.hasText(deployParam.getBuildCmd(), "buildCmd不能为空");
            Assert.hasText(deployParam.getRemoteFloder(), "remoteFloder不能为空");
        }
    }

    /* (non-Javadoc)
     * @see DeployService#deleteDeployJob(DeployParam)
     */
    @Override
    public ResponseVo<?> deleteDeployJob(@RequestBody DeployParam deployParam) {
        Assert.notNull(deployParam.getAppId(), "appId不能为空");
        Assert.hasText(deployParam.getEnvName(), "环境名称不能为空");

        BuildModel buildModelParam = new BuildModel();
        buildModelParam.setAppId(deployParam.getAppId());
        buildModelParam.setEnv(deployParam.getEnvName());
        BuildModel buildModel = buildModelService.selectOne(buildModelParam);
        Assert.isTrue(buildModel != null, "该应用不存在构建任务");

        ResponseVo<AppDetail> responseVo = appInfoService.queryAppDetailById(deployParam.getAppId());
        Assert.isTrue(responseVo.isSuccess(), responseVo.getMsg());

        buildModelService.deleteBuildModel(buildModel.getId(), deployParam.getEnvName(), responseVo.getData());
        return ResponseVo.getSuccessResponse();
    }

    /**
     * 功能描述: <br>
     * 根据环境查询所有构建模型
     *
     * @param env
     * @return
     */
    @Override
    public ResponseVo<List<BuildModelDto>> queryAllBuildModelByEnv(String env) {
        BuildModel buildModelParam = new BuildModel();
        buildModelParam.setEnv(env);
        List<BuildModel> list = buildModelService.selectList(buildModelParam);
        List<BuildModelDto> resultList = new ArrayList<>();
        for (BuildModel buildModel : list) {
            BuildModelDto buildModelDto = this.parseBuildModelDto(buildModel);
            resultList.add(buildModelDto);
        }
        return ResponseVo.getSuccessResponse(resultList);
    }

    private BuildModelDto parseBuildModelDto(BuildModel buildModel) {
        BuildModelDto buildModelDto = new BuildModelDto();
        buildModelDto.setAppId(buildModel.getAppId());
        buildModelDto.setCreateTime(buildModel.getCreateTime());
        buildModelDto.setId(buildModel.getId());
        buildModelDto.setEnv(buildModel.getEnv());
        buildModelDto.setModelJson(buildModel.getModelJson());
        buildModelDto.setSystemType(buildModel.getSystemType());
        return buildModelDto;
    }

    /* (non-Javadoc)
     * @see ModelService#queryBuildModelByApp(java.lang.Long)
     */
    @Override
    public ResponseVo<BuildModelDto> queryBuildModelByApp(Long appId,String env) {
        Assert.notNull(appId, "appId不能为空");
        Assert.hasText(env, "env不能为空");

        BuildModel buildModelParam = new BuildModel();
        buildModelParam.setAppId(appId);
        buildModelParam.setEnv(env);
        BuildModel buildModel = buildModelService.selectOne(buildModelParam);
        Assert.isTrue(buildModel != null, "该应用不存在构建任务");
        BuildModelDto buildModelDto = this.parseBuildModelDto(buildModel);
        return ResponseVo.getSuccessResponse(buildModelDto);
    }

    /* (non-Javadoc)
     * @see ModelService#queryBranchList(java.lang.String)
     */
    @Override
    public ResponseVo<List<String>> queryBranchList(Long appId,String env) {
        Assert.notNull(appId, "appId不能为空");
        Assert.hasText(env, "env不能为空");

        try {
            ResponseVo<AppDetail> responseVo = appInfoService.queryAppDetailById(appId);
            Assert.isTrue(responseVo.isSuccess(), responseVo.getMsg());
            AppDetail appDetail = responseVo.getData();

            boolean k8sFlag=false;
            List<Server> serverList = appDetail.getServerList();
            if(CollectionUtils.isNotEmpty(serverList)){
                for(Server server:serverList){
                    if(env.equals(server.getEnvName())){
                        k8sFlag=server.isK8s();
                        break;
                    }
                }
            }
            String jobName = k8sFlag ? appDetail.getName() + "-" + Server.K8S_HOSTNAME : appDetail.getName();
            return ResponseVo.getSuccessResponse(buildModelService.fetchBranch(jobName,false));
        } catch (Exception e) {
            logger.error("获取分支列表失败",e);
            return ErrorCodeEnum.ERROR_COMMON_SYSTEM.getResponseVo(e.getMessage());
        }

    }

}
